home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / m2 / cat3src / cat / doitk.i < prev    next >
Text File  |  1997-10-26  |  64KB  |  2,012 lines

  1. IMPLEMENTATION MODULE DoITK;
  2.  
  3. FROM SYSTEM     IMPORT ADDRESS, ADR, TSIZE, CADR, ASSEMBLER, CALLSYS;
  4.  
  5. (* MM2-Module *)
  6. FROM Storage    IMPORT ALLOCATE, DEALLOCATE;
  7. IMPORT Block, BinOps, Lists, Strings, StrConv, GrafBase;
  8. FROM Characters         IMPORT CR, LF, SUB;
  9.  
  10. (* Magic-Module *)
  11. IMPORT MagicStrings, MagicAES, mtTextfiles, mtAppl, mtUtils, mtDials, 
  12.        MagicDOS, mtAlerts;
  13. FROM MagicAES           IMPORT  GBOX, GIMAGE, GIBOX, GBUTTON, GSTRING,
  14.                                 SELECTABLE, DEFAULT, Exit, LASTOB, OUTLINED,
  15.                                 DRAW3D, SHADOWED, OBJECT, GrafMkstate, 
  16.                                 PtrBITBLK, GICON, FL3DBAK;
  17. FROM MagicSys   IMPORT  Nil, Null, Bit0, Bit1, Bit2, Bit3, Bit4, Bit5, Bit6,
  18.                         Bit7, Bit8, Bit9, Bit10, Bit11, Bit12, Bit13, Bit14,
  19.                         Bit15;
  20. (* CAT-Module *)
  21. FROM Void       IMPORT v;
  22.  
  23. IMPORT CatGlobal, CatTypes, Infofiles, MTE, MausTauschrsc, ListHelp, 
  24.        ListDl, WinDials, grin, WdwManager, ConvertDate, MTPaths,
  25.        CatUtil, ConfVars, Varnames, UserInformation, CatHelp,
  26.        QuickSort, Protokoll;
  27.  
  28. CONST   
  29.     maxInternalCmds = 8;
  30.  
  31.  
  32. TYPE    
  33.  
  34.     tIntCmdType = RECORD
  35.                     intIdent    : INTEGER;
  36.                     intVersion  : INTEGER;
  37.                   END;
  38.     
  39.     tInternalCmds = ARRAY [0..maxInternalCmds-1] OF tIntCmdType;
  40.     
  41.     MidTextPtr  = POINTER TO ARRAY [0..MAX(INTEGER)] OF CHAR;
  42.  
  43.     tCmdType    = (tcSingle,        (* TE *)
  44.                    tcMultiple,      (* TB *)
  45.                    tcConfig);       (* TK *)
  46.  
  47.     tParamType  = (tpConst,         (* C *)
  48.                    tpEnum,          (* FA *)    (* Buttons *)
  49.                    tpEnumSet,       (* FM *)    (* Buttons *)
  50.                    tpMTDate,        (* FD *)    (* Editfeld *)
  51.                    tpDate,          (* Fd *)    (* Editfeld *)
  52.                    tpString,        (* FS *)    (* Editfeld *)
  53.                    tpPassword,      (* FP *)    (* Editfeld *)
  54.                    tpNewPassword,   (* Fp *)    (* Editfeld *)
  55.                    tpUsername,      (* FU *)    (* Editfeld, Button *)
  56.                    tpInt,           (* FI *)    (* Editfeld num *)
  57.                    tpRange,         (* FIm,n *) (* Editfeld num *)
  58.                    tpGroup,         (* FG *)    (* Editfeld, Button *)
  59.                    tpChiefGroup);   (* Fg *)    (* Editfeld, Button *)
  60.                    
  61.     
  62.     OneCommand  = 
  63.       RECORD
  64.         cmdName : CatTypes.String255;   (* Name des Kommnandos *)
  65.         cmdHelp : MidTextPtr;           (* Hilfetext zum Kommando, 
  66.                                          * einzelne Zeilen mit CR/LF 
  67.                                          * getrennt *)
  68.         cmdVersion : INTEGER;           (* Versionsnummer des Kommandos *)
  69.         cmdIdent: INTEGER;              (* Identifikationsnummer des Kommandos *)
  70.         cmdType : tCmdType;             (* Kommandotyp *)
  71.         cmdParms: Lists.List;           (* Liste der Parameter *)
  72.         cmdGroup: ARRAY[0..7] OF CHAR;  (* Gruppe des Kommandos, Sortierkriterium *)
  73.         hasParms: BOOLEAN;
  74.         selected: BOOLEAN;            (* Fr Darstellung in Listbox *)
  75.       END;
  76.       
  77.     OneParam   = 
  78.       RECORD
  79.         paramName: CatTypes.String255;
  80.         paramHelp: MidTextPtr;
  81.         paramType: tParamType;
  82.         paramEnum: Lists.List;
  83.         paramDflt: CatTypes.String255;  (* Default-Wert fr Parameter *)
  84.         paramMin : LONGINT;             (* Min-Wert fr Integer-Bereich, ggf. Maxl„nge des Strings *)
  85.         paramMax : LONGINT;             (* Max-Wert fr Integer-Bereich *)
  86.         optional : BOOLEAN;             (* Parameter ist optional *)
  87.         hasEnums : BOOLEAN;             (* Hat Enum-Werte *)
  88.         obLow    : INTEGER;
  89.         obHigh   : INTEGER;
  90.       END;
  91.  
  92.     OneEnum    = 
  93.       RECORD
  94.         enumName:  CatTypes.String255;  (* Kurzbeschreibung des Enum-Parameters *)
  95.         enumValue: CatTypes.String255;  (* Werte dieses Enum-Parameters *)
  96.         obLow    : INTEGER;
  97.         obHigh   : INTEGER;
  98.       END;
  99.  
  100.     (* Zeiger auf die Datentypen *)    
  101.  
  102.     pOneCommand = POINTER TO OneCommand;
  103.     pOneParam   = POINTER TO OneParam;
  104.     pOneEnum    = POINTER TO OneEnum;
  105.  
  106. CONST
  107.     internalCmds = tInternalCmds{
  108.                    {1,0},           (* PMs anfordern *)
  109.                    {2,0},           (* eigene PMs zurcksenden *)
  110.                    {3,0},           (* PM-Status anfordern *)
  111.                    {4,0},           (* ”ffentliche Mitteilungen anfordern *)
  112.                    {5,0},           (* eigene ”ffentliche Mitteilungen zurcksenden *)
  113.                    {6,0},           (* Gruppenumbenennungsinformationen anfordern *)
  114.                    {8,0},           (* Maximalgr”že des Outfiles einstellen *)
  115.                    {36,0}           (* Gruppen bestellen/abstellen *)
  116.                    };
  117.  
  118. CONST   noITKAlert = "[1][CAT:|Das Infofile ITK steht nicht|zur Verfgung!][[OK]";
  119.  
  120.         OkBut       = "[OK";
  121.         CancelBut   = "[Abbruch";
  122.         PreviewBut  = "[Preview";
  123.         HelpBut     = "Help";
  124.  
  125.         eEnumCheck1     = "[3][CAT:|Aus der Aufz„hlung|'";
  126.         eEnumCheck2     = "'|muž mindestens ein Wert|selektiert werden!][[OK]";
  127.         eEmptyParm1     = "[3][CAT:|Der Parameter|'";
  128.         eEmptyParm2     = "'|darf nicht leer sein!][[OK]";
  129.         eDateAlt1       = "[3][CAT:|Der Wert im Feld|'";
  130.         eDateAlt2       = "'|ist kein gltiges Datum!][[OK]";
  131.         eRangeAlt1      = "[3][CAT:|Der Wert im Feld|'";
  132.         eRangeAlt2      = "'|muž zwischen ";
  133.         eRangeAlt3      = " und ";
  134.         eRangeAlt4      = "|liegen!][[OK]";
  135.         eSaveCmd1       = "[2][CAT:|Soll die Einstellung fr das Kommando|'";
  136.         eSaveCmd2       = "'|dauerhaft gespeichert werden oder|soll es nur einmal gesendet werden?][[Speichern|[Einmal|:[Abbruch]";
  137.         eSaveConfig     = "[2][CAT:|Die Konfiguration wurde ge„ndert.|Damit diese Einstellung erhalten|bleibt, mssen die Optionen gesichert werden.|Optionen jetzt sichern?][[Speichern|:[Abbruch]";
  138.         eDataType       = "[3][CAT:|In der ITK ist ein unbekannter|Datentyp bei Kommando & enthalten.][:[Abbruch]";
  139.         eUnknown        = "[3][CAT:|Beim Parsen der ITK ist|ein unerwarteter Fehler aufgetreten.|Bitte schicken sie das ITK|an Dirk Steins @ K2][:[Abbruch]";
  140.         ePreview1       = "[1][CAT:|Das Kommando fr die MAUS sieht mit|den aktuellen Daten wie folgt aus:|'";
  141.         ePreview2       = "'][[OK]";
  142.  
  143.         errMemErr       = 2000;
  144.         errDataType     = 2001;
  145.  
  146.  
  147. VAR     cmds            : Lists.List;        
  148.         globalLength    : INTEGER;
  149.  
  150. CONST   cMaxChars =     255;    (* Maximale Zeichenzahl pro Zeile *)
  151.         cMaxText =        9;    (* Maximale Anzahl Zeilen *)
  152.         cMaxButt =        4;    (* Maximale Anzahl Buttons *)
  153.         cMaxIcon =      256;    (* Maximale Anzahl Iconslots *)
  154.         cMaxTeds =        9;    (* Maximale Anzahl Editfelder *)
  155.         
  156. CONST   Box =           0;
  157.         Mover =         1;
  158.         Header =        2;      (* šberschrift *)
  159.  
  160. CONST   Left =          0;
  161.         Center =        1;
  162.         Right =         2;
  163.  
  164. TYPE    tString =       ARRAY [0..cMaxChars-1] OF CHAR;
  165.         ShortKeys =     ['A'..'Z'];
  166.         KeySet =        SET OF ShortKeys;
  167.  
  168. VAR     Tree:           ARRAY [0..255] OF MagicAES.OBJECT;
  169.         Teds:           ARRAY [0..cMaxTeds] OF MagicAES.TEDINFO;
  170.         Text:           ARRAY [0..cMaxText] OF tString;
  171.         Button:         ARRAY [0..cMaxButt] OF RECORD
  172.                                                 text: tString;
  173.                                                 objc: INTEGER;
  174.                                                END;
  175.         currObIdx:      INTEGER;
  176.         tedIdx:         INTEGER;
  177.         theTree:        mtUtils.tObjcTree;
  178.         lastyPos:       INTEGER;
  179.         globErr:        INTEGER;
  180.         lastCmd:        INTEGER;
  181.         
  182.         helpButIdx:     INTEGER;
  183.         okButIdx:       INTEGER;
  184.         cancelButIdx:   INTEGER;
  185.         previewButIdx:  INTEGER;
  186.         usedKeys:       KeySet;
  187.  
  188.         CmdBox:         ADDRESS;
  189.  
  190. (*----------------------------------------------------------------------
  191.  * Zusatzfunktionen fr die Listen
  192.  *----------------------------------------------------------------------*)
  193.  
  194. TYPE    delEntryProc = PROCEDURE (VAR ADDRESS);
  195.  
  196.  
  197. PROCEDURE DeleteSimpleList (VAR l: Lists.List; killCarrier: BOOLEAN;
  198.                             deleteEntry : delEntryProc);
  199.  
  200. VAR   entry: ADDRESS;
  201.  
  202. BEGIN
  203.   Lists.ResetList (l);
  204.   entry := Lists.PrevEntry (l);
  205.   WHILE entry # NIL DO
  206.     Lists.RemoveEntry (l, v.bool);
  207.     deleteEntry (entry);
  208.     entry := Lists.CurrentEntry (l);
  209.   END;
  210.   IF killCarrier THEN Lists.DeleteList (l, v.bool) END;
  211. END DeleteSimpleList;
  212.  
  213. PROCEDURE delEnum (VAR entry : ADDRESS);
  214. BEGIN
  215.   DEALLOCATE (entry, 0);
  216. END delEnum;
  217.  
  218. PROCEDURE delParam (VAR entry : ADDRESS);
  219.   VAR pParam  : pOneParam;
  220. BEGIN
  221.   pParam := entry;
  222.   IF pParam^.hasEnums
  223.   THEN
  224.     DeleteSimpleList (pParam^.paramEnum, TRUE, delEnum);
  225.   END;
  226.   IF pParam^.paramHelp # NIL
  227.   THEN
  228.     DEALLOCATE (pParam^.paramHelp, 0);
  229.   END;
  230.   DEALLOCATE (entry, 0);
  231. END delParam;
  232.  
  233. PROCEDURE delCmd (VAR entry : ADDRESS);
  234.   VAR pCmd  : pOneCommand;
  235. BEGIN
  236.   pCmd := entry;
  237.   IF pCmd^.hasParms
  238.   THEN
  239.     DeleteSimpleList (pCmd^.cmdParms, TRUE, delParam);
  240.   END;
  241.   IF pCmd^.cmdHelp # NIL
  242.   THEN
  243.     DEALLOCATE (pCmd^.cmdHelp, 0);
  244.   END;
  245.   DEALLOCATE (entry, 0);
  246. END delCmd;
  247.  
  248. (*----------------------------------------------------------------------
  249.  * Interne Stringfunktionen
  250.  *----------------------------------------------------------------------*)
  251.  
  252. PROCEDURE StripShortcut (REF paramName: ARRAY OF CHAR;
  253.                          VAR pName : ARRAY OF CHAR);
  254.   VAR p : INTEGER;
  255. BEGIN
  256.   MagicStrings.Assign (paramName, pName);
  257.   p := Strings.Pos ("[", pName, 0);
  258.   IF p >= 0
  259.   THEN
  260.     MagicStrings.Delete (pName, p, 1);
  261.   END;
  262. END StripShortcut;
  263.  
  264.  
  265. (*----------------------------------------------------------------------
  266.  * Hilfe zu einem Kommando zusammenbauen
  267.  *----------------------------------------------------------------------*)
  268. TYPE tHelpLine  = ARRAY [0..70] OF CHAR;
  269.      pHelpLine  = POINTER TO tHelpLine;
  270.  
  271. CONST   helpLineLength = 65;
  272.      
  273. PROCEDURE AddToHelp (REF str: ARRAY OF CHAR; VAR helpList: Lists.List): BOOLEAN;
  274.   VAR helpLine : pHelpLine;
  275.       fromPos,
  276.       toPos    : INTEGER;
  277. BEGIN
  278.   IF str[0] # 0C
  279.   THEN
  280.     NEW (helpLine);
  281.     IF helpLine = NIL
  282.     THEN
  283.       MTE.noMemAlert();
  284.       DeleteSimpleList (helpList, TRUE, delEnum);
  285.       RETURN FALSE;
  286.     END;
  287.     fromPos := 0;
  288.     toPos := LENGTH (str);
  289.     WHILE (fromPos < toPos) DO
  290.       NEW (helpLine);
  291.       IF helpLine = NIL
  292.       THEN
  293.         MTE.noMemAlert();
  294.         DeleteSimpleList (helpList, TRUE, delEnum);
  295.         RETURN FALSE;
  296.       END;
  297.       IF toPos - fromPos > helpLineLength - 1 
  298.       THEN
  299.         (* Umbruch an Wortgrenze durchfhren *)
  300.         toPos := fromPos  + helpLineLength-1;
  301.         WHILE (str[toPos] # ' ') & (toPos > fromPos) DO DEC (toPos); END;
  302.         IF toPos = fromPos THEN toPos := fromPos + helpLineLength - 1 END;
  303.       END;
  304.       MagicStrings.Copy (str, fromPos, toPos - fromPos, helpLine^);
  305.       Lists.AppendEntry (helpList, helpLine, v.bool);
  306.       IF v.bool
  307.       THEN
  308.         MTE.noMemAlert();
  309.         DeleteSimpleList (helpList, TRUE, delEnum);
  310.         RETURN FALSE
  311.       END;
  312.       fromPos := toPos + 1;
  313.       toPos := LENGTH (str);
  314.     END;
  315.   END;
  316.   RETURN TRUE;
  317. END AddToHelp;
  318.  
  319. PROCEDURE AddParmHelp (pParm: pOneParam; VAR helpList: Lists.List): BOOLEAN;
  320.   VAR pName : CatTypes.String255;
  321. BEGIN
  322.   WITH pParm^ DO
  323.     IF paramHelp # NIL
  324.     THEN
  325.       StripShortcut (paramName, pName);
  326.       MagicStrings.Insert ("Parameter: ", pName, 0);
  327.       IF ~AddToHelp (pName, helpList)
  328.       THEN
  329.         RETURN FALSE
  330.       END;
  331.       IF ~AddToHelp (" ", helpList)
  332.       THEN
  333.         RETURN FALSE
  334.       END;
  335.       IF ~AddToHelp (paramHelp^, helpList)
  336.       THEN
  337.         RETURN FALSE
  338.       END;
  339.       IF ~AddToHelp (" ", helpList)
  340.       THEN
  341.         RETURN FALSE
  342.       END;
  343.     END;
  344.   END;
  345.   RETURN TRUE;
  346. END AddParmHelp;
  347.  
  348. PROCEDURE BuildHelp (pCmd: pOneCommand; VAR helpList: Lists.List): BOOLEAN;
  349.   VAR pParm : pOneParam;
  350. BEGIN
  351.   WITH pCmd^ DO
  352.     Lists.CreateList (helpList, v.bool);
  353.     IF v.bool
  354.     THEN
  355.       MTE.noMemAlert();
  356.       RETURN FALSE;
  357.     END;
  358.     IF cmdHelp # NIL
  359.     THEN
  360.       IF ~AddToHelp (cmdName, helpList)
  361.       THEN
  362.         RETURN FALSE
  363.       END;
  364.       IF ~AddToHelp (" ", helpList)
  365.       THEN
  366.         RETURN FALSE
  367.       END;
  368.       IF ~AddToHelp (cmdHelp^, helpList)
  369.       THEN
  370.         RETURN FALSE
  371.       END;
  372.       IF ~AddToHelp (" ", helpList)
  373.       THEN
  374.         RETURN FALSE
  375.       END;
  376.     END;
  377.     IF hasParms
  378.     THEN
  379.       Lists.ResetList (cmdParms);
  380.       pParm := Lists.NextEntry (cmdParms);
  381.       WHILE pParm # NIL DO
  382.         IF ~AddParmHelp (pParm, helpList) THEN RETURN FALSE END;
  383.         pParm := Lists.NextEntry (cmdParms);
  384.       END;
  385.     END;
  386.   END;
  387.   RETURN TRUE;
  388. END BuildHelp;
  389.  
  390. (*----------------------------------------------------------------------
  391.  * ITK Dialogboxen zusammenbauen
  392.  *----------------------------------------------------------------------*)
  393.  
  394. PROCEDURE SetObjc (objc, typ, x, y, w, h: INTEGER; f, s: BITSET; 
  395.                    spec: ADDRESS);
  396. BEGIN
  397.  Tree[objc].obNext:= -1;
  398.  Tree[objc].obHead:= -1;
  399.  Tree[objc].obTail:= -1;
  400.  Tree[objc].obType:= typ;
  401.  Tree[objc].obFlags:= f;
  402.  Tree[objc].obState:= s;
  403.  Tree[objc].obSpec.address:= spec;
  404.  Tree[objc].obX:= x;
  405.  Tree[objc].obY:= y;
  406.  Tree[objc].obWidth:= w;
  407.  Tree[objc].obHeight:= h;
  408.  MagicAES.ObjcAdd (theTree, Box, objc);
  409.  Tree[Box].obWidth := BinOps.HigherInt (x+w, Tree[Box].obWidth);
  410.  Tree[Box].obHeight := BinOps.HigherInt (y+h, Tree[Box].obHeight);
  411. END SetObjc;
  412.  
  413. PROCEDURE PrepareTree (VAR title: ARRAY OF CHAR);
  414. BEGIN
  415.  theTree := ADR (Tree);
  416.  Tree[Box].obNext:= -1;
  417.  Tree[Box].obHead:= -1;
  418.  Tree[Box].obTail:= -1;
  419.  Tree[Box].obType:= GBOX;
  420.  Tree[Box].obFlags:= {FL3DBAK};
  421.  Tree[Box].obState:= {OUTLINED};
  422.  Tree[Box].obSpec.Box.char:= 0C;
  423.  Tree[Box].obSpec.Box.frame:= 2C;
  424.  (* Tree[Box].obSpec.Box.flags:= {Bit0,Bit11, Bit12}; *)
  425.  Tree[Box].obSpec.Box.flags:= {Bit11, Bit12};
  426.  Tree[Box].obX:= 0;  Tree[Box].obY:= 0;
  427.  Tree[Box].obWidth:= 0;
  428.  Tree[Box].obHeight:= 0;
  429.  SetObjc (Mover, 1119H, 0, 0, 16, 16, {}, {OUTLINED}, Null);
  430.  Tree[Mover].obSpec.Box.char:= 0C;
  431.  Tree[Mover].obSpec.Box.frame:= 1C;
  432.  Tree[Mover].obSpec.Box.flags:= {Bit11, Bit12};
  433.  (* Titelzeile hinzufgen *)
  434.  SetObjc (Header, 131CH, 2 * mtAppl.CharWidth, mtAppl.CharHeight, INTEGER(LENGTH(title)) * mtAppl.CharWidth, 0, {}, {MagicAES.SHADOWED}, ADR(title));
  435.  currObIdx := Header+1;
  436.  tedIdx := 0;
  437.  lastyPos := currObIdx * mtAppl.CharHeight;
  438.  usedKeys := KeySet{'A','O','P'};
  439. END PrepareTree;
  440.  
  441. PROCEDURE CalcCoords (REF text: ARRAY OF CHAR; VAR x, y, w, h: INTEGER);
  442. BEGIN
  443.   h := mtAppl.CharHeight;
  444.   x := mtAppl.CharWidth * 2;
  445.   y := lastyPos + mtAppl.CharHeight;
  446.   lastyPos := y;
  447.   w := mtAppl.CharWidth * INTEGER(LENGTH (text)+4);
  448. END CalcCoords;
  449.  
  450. PROCEDURE CalcCoords2 (REF name: ARRAY OF CHAR; maxLen: INTEGER; VAR x, y, w, h: INTEGER);
  451. BEGIN
  452.   DEC (lastyPos, mtAppl.CharHeight);
  453.   CalcCoords (name, x, y, w, h);
  454.   x := x + w - 2 * mtAppl.CharWidth;
  455.   IF maxLen > 50 
  456.   THEN 
  457.     maxLen := 50;
  458.   END;
  459.   IF maxLen = 0
  460.   THEN 
  461.     maxLen := 50;
  462.   END;
  463.   w := mtAppl.CharWidth * (maxLen + 1);
  464. END CalcCoords2;
  465.  
  466. PROCEDURE CalcEdButCoords (maxLen: INTEGER; VAR x, y, w, h: INTEGER);
  467. BEGIN
  468.   x := x + w + 2 * mtAppl.CharWidth;
  469.   IF maxLen > 50 
  470.   THEN 
  471.     maxLen := 50;
  472.   END;
  473.   IF maxLen = 0
  474.   THEN 
  475.     maxLen := 50;
  476.   END;
  477.   w := mtAppl.CharWidth * (maxLen + 4);
  478. END CalcEdButCoords;
  479.  
  480. PROCEDURE AddShortcut (VAR name: ARRAY OF CHAR);
  481.   VAR l : CARDINAL;
  482.       i : CARDINAL;
  483.       ch: CHAR;
  484. BEGIN
  485.   l := LENGTH (name);
  486.   i := 0; 
  487.   ch := CAP (name[i]);
  488.   WHILE (i < l) & 
  489.         ((ch IN usedKeys) OR (ch < 'A') OR (ch > 'Z')) 
  490.   DO 
  491.     INC (i);
  492.     ch := CAP (name[i]);
  493.   END;
  494.   IF (i < l)
  495.   THEN
  496.     (* freien Shortcut gefunden *)
  497.     INCL (usedKeys, ch);
  498.     MagicStrings.Insert ("[", name, i);
  499.   END;
  500. END AddShortcut;
  501.  
  502. PROCEDURE AddCheckButton (VAR name: ARRAY OF CHAR; threeState: BOOLEAN): INTEGER;
  503. (* Check: Ext 18
  504.  * Three: Ext 23
  505.  *)
  506.  VAR obType : CARDINAL;     (* Vereinigt normalen und erweiterten Objekttyp *)
  507.      x, y, w, h : INTEGER;
  508. BEGIN
  509.   IF threeState
  510.   THEN
  511.     obType := mtDials.ThreeState * 256 + MagicAES.GBUTTON;
  512.   ELSE
  513.     obType := mtDials.SpecButton * 256 + MagicAES.GBUTTON;
  514.   END;
  515.   CalcCoords (name, x, y, w, h);
  516.   AddShortcut (name);
  517.   SetObjc (currObIdx, obType, x, y, w, h, {MagicAES.SELECTABLE}, {}, ADR(name));
  518.   INC (currObIdx);
  519.   RETURN currObIdx - 1;
  520. END AddCheckButton;
  521.  
  522. PROCEDURE AddRadioButton (parent: INTEGER; VAR name: ARRAY OF CHAR): INTEGER;
  523. (* Check: Ext 18
  524.  * Three: Ext 23
  525.  *)
  526.  VAR obType : CARDINAL;     (* Vereinigt normalen und erweiterten Objekttyp *)
  527.      x, y, w, h : INTEGER;
  528. BEGIN
  529.   obType := mtDials.SpecButton * 256 + MagicAES.GBUTTON;
  530.   CalcCoords (name, x, y, w, h);
  531.   AddShortcut (name);
  532.   SetObjc (currObIdx, obType, x, y, w, h, {MagicAES.SELECTABLE, MagicAES.RBUTTON}, {}, ADR(name));
  533.   (* Tree[currObIdx].obHead := parent; *)
  534.   INC (currObIdx);
  535.   RETURN currObIdx - 1;
  536. END AddRadioButton;
  537.  
  538. (*
  539. PROCEDURE AddParent (): INTEGER;
  540. BEGIN
  541.   obType := MagicAES.GIBOX;
  542.   CalcCoords3 (x, y, w, h);
  543.   SetObjc (currObIdx, obType, x, y, w, h, {}, {}, Null);
  544.   INC (currObIdx);
  545.   RETURN currObIdx - 1;
  546. END AddParent;
  547. *)
  548.  
  549. PROCEDURE AddText (VAR name: ARRAY OF CHAR): INTEGER;
  550. (* Check: Ext 18
  551.  * Three: Ext 23
  552.  *)
  553.  VAR obType : CARDINAL;     (* Vereinigt normalen und erweiterten Objekttyp *)
  554.      x, y, w, h : INTEGER;
  555. BEGIN
  556.   obType := MagicAES.GSTRING;
  557.   CalcCoords (name, x, y, w, h);
  558.   SetObjc (currObIdx, obType, x, y, w, h, {}, {}, ADR(name));
  559.   INC (currObIdx);
  560.   RETURN currObIdx - 1;
  561. END AddText;
  562.  
  563. PROCEDURE PrepareEdit (isNum: BOOLEAN; maxLength: INTEGER; REF default: ARRAY OF CHAR;
  564.                        VAR obType: CARDINAL);
  565.   VAR validChar : CHAR;
  566.       i         : INTEGER;
  567. BEGIN
  568.   IF (maxLength = 0) & ~isNum
  569.   THEN
  570.     maxLength := 255;
  571.   ELSIF (maxLength = 0) & isNum
  572.   THEN
  573.     maxLength := 10;
  574.   END;
  575.   IF (maxLength > 50) & ~isNum
  576.   THEN
  577.     obType := mtDials.LongEdit * 256 + MagicAES.GFTEXT;
  578.   ELSE
  579.     obType := MagicAES.GFTEXT;
  580.   END;
  581.   WITH Teds[tedIdx] DO
  582.     ALLOCATE (tePtext, maxLength + 1);
  583.     ALLOCATE (tePvalid, maxLength + 1);
  584.     ALLOCATE (tePtmplt, maxLength + 1);
  585.     teFont := MagicAES.IBM;
  586.     teFontid    := 0;
  587.     teJust      := 0;
  588.     teColor     := INTEGER({Bit7, Bit8});
  589.     teFontsize  := 0;
  590.     teThickness := 0;
  591.     teTxtlen := maxLength;
  592.     teTmplen := maxLength;
  593.     MagicStrings.Assign (default, tePtext^);
  594.     IF isNum
  595.     THEN
  596.       validChar := '9';
  597.     ELSE
  598.       validChar := 'X';
  599.     END;
  600.     FOR i := 0 TO maxLength - 1 DO
  601.       tePvalid^[i] := validChar;
  602.       tePtmplt^[i] := '_';
  603.     END;
  604.     tePvalid^[maxLength] := 0C;
  605.     tePtmplt^[maxLength] := 0C;
  606.   END;
  607. END PrepareEdit;
  608.  
  609. PROCEDURE AddEditField (VAR name: ARRAY OF CHAR; isNum: BOOLEAN; 
  610.                         maxLength: INTEGER; REF default: ARRAY OF CHAR): INTEGER;
  611.   VAR obType : CARDINAL;
  612.       x, y, w, h : INTEGER;
  613. BEGIN
  614.   PrepareEdit (isNum, maxLength, default, obType);
  615.   v.int := AddText (name);
  616.   CalcCoords2 (name, maxLength, x, y, w, h);
  617.  
  618.   SetObjc (currObIdx, obType, x, y, w, h, {MagicAES.EDITABLE}, {}, ADR(Teds[tedIdx]));
  619.   INC (tedIdx);
  620.   INC (currObIdx);
  621.   RETURN currObIdx - 1;
  622. END AddEditField;
  623.  
  624.  
  625. PROCEDURE AddHelpBut(x, y, w, h : INTEGER);
  626. BEGIN
  627.   WITH Teds[tedIdx] DO
  628.     ALLOCATE (tePtext, LENGTH (HelpBut)+1);
  629.     tePvalid := NIL;
  630.     tePtmplt := NIL;
  631.     teFont := MagicAES.SMALL;
  632.     teFontid    := 0;
  633.     teJust      := 2;
  634.     teColor     := INTEGER({Bit7, Bit8, Bit12});
  635.     teFontsize  := 0;
  636.     teThickness := -1;
  637.     teTxtlen := LENGTH (HelpBut);
  638.     teTmplen := 0;
  639.     MagicStrings.Assign (HelpBut, tePtext^);
  640.   END;
  641.   SetObjc (currObIdx, MagicAES.GBOXTEXT, x, y, w, h, {MagicAES.SELECTABLE, MagicAES.Exit, Bit15}, {MagicAES.OUTLINED, MagicAES.SHADOWED}, ADR(Teds[tedIdx]));
  642.   INC (tedIdx);
  643.   helpButIdx := currObIdx;
  644.   INC (currObIdx);
  645. END AddHelpBut;
  646.  
  647. PROCEDURE AddExitButs();
  648.   VAR obType : CARDINAL;
  649.       x, y, w, h : INTEGER;
  650. BEGIN
  651.   (* Hilfe-, Preview-, OK- und Abbruch-Button hinzufgen *)
  652.   (* Es werden zwei Reihen hinzugefgt, in der oberen der Hilfe- 
  653.    * und der OK-Button, jeweils darunter der Preview- und Abbruch-
  654.    * Button. Das sieht dann ungef„hr so aus:
  655.    *
  656.    * |  +------------+                      +-------------+  |
  657.    * |  |   Help     |                      |     OK      |  |
  658.    * |  +------------+                      +-------------+  |
  659.    * |                                                       |
  660.    * |  +------------+                      +-------------+  |
  661.    * |  |  Preview   |                      |   Abbruch   |  |
  662.    * |  +------------+                      +-------------+  |
  663.    * +-------------------------------------------------------+
  664.    *
  665.    *)
  666.   (* Breite um fnf Zeichen vergr”žern  *)  
  667.   Tree[Box].obWidth := Tree[Box].obWidth + 5 * mtAppl.CharWidth;
  668.   obType := mtDials.SpecButton * 256 + MagicAES.GBUTTON;
  669.   (* Position berechnen *)
  670.   h := mtAppl.CharHeight;
  671.   w := mtAppl.CharWidth * INTEGER(LENGTH (CancelBut)+2);
  672.   Tree[Box].obWidth := BinOps.HigherInt (Tree[Box].obWidth, 2 * w + 6 * mtAppl.CharWidth);
  673.   x := 2 * mtAppl.CharWidth;
  674.   y := lastyPos + 2 * mtAppl.CharHeight;
  675.   (* Hilfebutton hinzufgen *)
  676.   AddHelpBut (x, y, w, h);
  677.  
  678.   x := Tree[Box].obWidth - 2 * mtAppl.CharWidth - w;
  679.   SetObjc (currObIdx, obType, x, y, w, h, {MagicAES.SELECTABLE, MagicAES.DEFAULT, MagicAES.Exit}, {}, CADR(OkBut));
  680.   okButIdx := currObIdx;
  681.   INC (currObIdx);
  682.   (* Jetzt Preview- und Abbruch-Button *)
  683.  
  684.   (* Previewbutton *)
  685.   x := 2 * mtAppl.CharWidth;
  686.   y := lastyPos + 4 * mtAppl.CharHeight;
  687.   SetObjc (currObIdx, obType, x, y, w, h, {MagicAES.SELECTABLE, MagicAES.Exit}, {}, CADR(PreviewBut));
  688.   previewButIdx := currObIdx;
  689.   INC (currObIdx);
  690.   (* OK-Button *)
  691.   x := Tree[Box].obWidth - 2 * mtAppl.CharWidth - w;
  692.   SetObjc (currObIdx, obType, x, y, w, h, {MagicAES.SELECTABLE, MagicAES.Exit, Bit14, MagicAES.LASTOB}, {}, CADR(CancelBut));
  693.   cancelButIdx := currObIdx;
  694.   INC (currObIdx);
  695.   Tree[Box].obHeight := lastyPos + 6 * mtAppl.CharHeight;
  696. END AddExitButs;
  697.  
  698. PROCEDURE AddGroupSelect (VAR name: ARRAY OF CHAR; chiefGroup: BOOLEAN;
  699.                           maxLength: INTEGER; REF default: ARRAY OF CHAR): INTEGER;
  700.   VAR obType    : CARDINAL;
  701.       state     : BITSET;
  702.       x, y, w, h : INTEGER;
  703. BEGIN
  704.   (* Button mit Bit fr Groupselect gesetzt *)
  705.   obType := mtDials.SpecButton * 256 + MagicAES.GBUTTON;
  706.   IF chiefGroup
  707.   THEN
  708.     state := {Bit14};
  709.   ELSE
  710.     state := {Bit15};
  711.   END;
  712.   CalcCoords (name, x, y, w, h);
  713.   AddShortcut (name);
  714.   IF (currObIdx > Header+1)
  715.   THEN
  716.     INC (y, mtAppl.CharHeight);
  717.     INC (lastyPos, mtAppl.CharHeight);
  718.   END;
  719.   SetObjc (currObIdx, obType, x, y, w, h, {MagicAES.SELECTABLE, MagicAES.Exit}, state, ADR(name));
  720.   INC (currObIdx);
  721.   
  722.   (* Editfeld hinzufgen *)
  723.   PrepareEdit (FALSE, maxLength, default, obType);
  724.   CalcEdButCoords (maxLength, x, y, w, h);
  725.   SetObjc (currObIdx, obType, x, y, w, h, {MagicAES.EDITABLE}, {}, ADR(Teds[tedIdx]));
  726.   INC (tedIdx);
  727.   INC (currObIdx);
  728.   INC (lastyPos, mtAppl.CharHeight);
  729.   RETURN currObIdx - 1;
  730. END AddGroupSelect;
  731.  
  732. PROCEDURE AddUserSelect (VAR name: ARRAY OF CHAR; maxLength: INTEGER; REF default: ARRAY OF CHAR): INTEGER;
  733.   VAR obType    : CARDINAL;
  734.       x, y, w, h : INTEGER;
  735.       defName   : CatTypes.String255;
  736.       botWdw    : INTEGER;
  737. BEGIN
  738.   (* Button mit Bit fr Groupselect gesetzt *)
  739.   obType := mtDials.SpecButton * 256 + MagicAES.GBUTTON;
  740.   CalcCoords (name, x, y, w, h);
  741.   AddShortcut (name);
  742.   IF (currObIdx > Header+1)
  743.   THEN
  744.     INC (y, mtAppl.CharHeight);
  745.     INC (lastyPos, mtAppl.CharHeight);
  746.   END;
  747.   SetObjc (currObIdx, obType, x, y, w, h, {MagicAES.SELECTABLE, MagicAES.Exit}, {Bit13}, ADR(name));
  748.   INC (currObIdx);
  749.  
  750.   (* Editfeld hinzufgen *)
  751.   IF default[0] = 0C
  752.   THEN
  753.     (* Aktuellen User abfragen *)
  754.     IF grin.grinWindowTop (WdwManager.ownTopWindow)
  755.     THEN
  756.       grin.ActualFrom (WdwManager.ownTopWindow, defName);
  757.     ELSIF (WdwManager.GetSecondWdw (botWdw) 
  758.            & grin.grinWindowTop (botWdw)) OR
  759.           grin.grinOnlyOneWind (botWdw)
  760.     THEN 
  761.       grin.ActualFrom (botWdw, defName);
  762.     END;
  763.     PrepareEdit (FALSE, maxLength, defName, obType);
  764.   ELSE
  765.     PrepareEdit (FALSE, maxLength, default, obType);
  766.   END;
  767.  
  768.   CalcEdButCoords (maxLength, x, y, w, h);
  769.   SetObjc (currObIdx, obType, x, y, w, h, {MagicAES.EDITABLE}, {}, ADR(Teds[tedIdx]));
  770.   INC (tedIdx);
  771.   INC (currObIdx);
  772.   INC (lastyPos, mtAppl.CharHeight);
  773.   RETURN currObIdx - 1;
  774. END AddUserSelect;
  775.  
  776. PROCEDURE AddRadioEnums (paramEnums: Lists.List);
  777.   VAR pEnum : pOneEnum;
  778.       count : INTEGER;
  779. BEGIN
  780.   count := Lists.NoOfEntries (paramEnums);
  781.   Lists.ResetList (paramEnums);
  782.   pEnum := Lists.NextEntry (paramEnums);
  783.   WHILE pEnum # NIL DO
  784.     IF count = 1
  785.     THEN
  786.       pEnum^.obLow := AddCheckButton (pEnum^.enumName, FALSE);
  787.     ELSE
  788.       pEnum^.obLow := AddRadioButton (Box, pEnum^.enumName);
  789.     END;
  790.     pEnum := Lists.NextEntry (paramEnums);
  791.   END;
  792. END AddRadioEnums;
  793.  
  794. PROCEDURE CheckEnumValue (REF str: ARRAY OF CHAR): INTEGER;
  795.   VAR count: INTEGER;
  796.       pos  : INTEGER;
  797. BEGIN
  798.   pos := 0;
  799.   count := 0;
  800.   WHILE pos >= 0 DO
  801.     pos := Strings.Pos (":", str, pos);
  802.     IF pos >= 0 THEN INC (pos) END;
  803.     INC (count);
  804.   END;
  805.   RETURN count;
  806. END CheckEnumValue;
  807.  
  808. PROCEDURE AddCheckEnums (paramEnums: Lists.List);
  809.   VAR pEnum : pOneEnum;
  810.       count : INTEGER;
  811. BEGIN
  812.   Lists.ResetList (paramEnums);
  813.   pEnum := Lists.NextEntry (paramEnums);
  814.   WHILE pEnum # NIL DO
  815.     count := CheckEnumValue (pEnum^.enumValue);
  816.     IF count < 3
  817.     THEN 
  818.       pEnum^.obLow := AddCheckButton (pEnum^.enumName, FALSE);
  819.     ELSIF count = 3
  820.     THEN
  821.       pEnum^.obLow := AddCheckButton (pEnum^.enumName, TRUE);
  822.     ELSE
  823.       (* Nicht behandelbar momentan *)
  824.     END;
  825.     pEnum := Lists.NextEntry (paramEnums);
  826.   END;
  827. END AddCheckEnums;
  828.  
  829. PROCEDURE AddParamObjcs (pParam: pOneParam);
  830. BEGIN
  831.   WITH pParam^ DO
  832.     CASE paramType OF
  833.       tpConst   : RETURN; |
  834.       tpEnum    : IF hasEnums 
  835.                   THEN 
  836.                     AddRadioEnums (paramEnum);
  837.                   END; |
  838.       tpEnumSet : IF hasEnums 
  839.                   THEN 
  840.                     AddCheckEnums (paramEnum);
  841.                   END; |
  842.       tpMTDate,
  843.       tpDate    : obLow := AddEditField (paramName, FALSE, 12, paramDflt); |
  844.       tpString,
  845.       tpPassword,
  846.       tpNewPassword:
  847.                   obLow := AddEditField (paramName, FALSE, SHORT(paramMin), paramDflt); |
  848.       tpInt,
  849.       tpRange:    obLow := AddEditField (paramName, TRUE, 10, paramDflt); |
  850.       tpGroup,
  851.       tpChiefGroup:
  852.                   (* Button und dahinter Editfeld *)
  853.                   obLow := AddGroupSelect (paramName, paramType = tpChiefGroup,
  854.                                            SHORT(paramMin), paramDflt); |
  855.       tpUsername:
  856.                   (* Button und dahinter Editfeld *)
  857.                   obLow := AddUserSelect (paramName, SHORT(paramMin), paramDflt); |
  858.     ELSE
  859.     END;
  860.   END;
  861. END AddParamObjcs;
  862.  
  863. PROCEDURE BuildTree (VAR pCmd : pOneCommand);
  864.   VAR pParam    : pOneParam;
  865. BEGIN
  866.   WITH pCmd^ DO
  867.     PrepareTree (cmdName);
  868.     IF hasParms
  869.     THEN
  870.       Lists.ResetList (cmdParms);
  871.       pParam := Lists.NextEntry (cmdParms);
  872.       WHILE pParam # NIL DO
  873.         AddParamObjcs (pParam);
  874.         pParam := Lists.NextEntry (cmdParms);
  875.       END;
  876.     END;
  877.     AddExitButs();
  878.     (* Mover noch verschieben *)
  879.     Tree[Mover].obX:= Tree[Box].obWidth - Tree[Mover].obWidth;
  880.   END;
  881. END BuildTree;
  882.  
  883. PROCEDURE RemoveTree ();
  884. (* Allozierten Speicher fr Editfelder wieder freigeben *)
  885.   VAR i : INTEGER;
  886. BEGIN
  887.   FOR i := 0 TO tedIdx - 1 DO
  888.     WITH Teds[i] DO
  889.       DEALLOCATE (tePtext, 0);
  890.       DEALLOCATE (tePvalid, 0);
  891.       DEALLOCATE (tePtmplt, 0);
  892.     END;
  893.   END;
  894. END RemoveTree;
  895.  
  896. (*----------------------------------------------------------------------
  897.  * ITK Werte aus Dialogbox auslesen 
  898.  *----------------------------------------------------------------------*)
  899.  
  900. PROCEDURE GetEnumValue (idx: INTEGER; REF str: ARRAY OF CHAR; 
  901.                         VAR target: ARRAY OF CHAR);
  902.   VAR count     : INTEGER;
  903.       lastPos   : INTEGER;
  904.       pos       : INTEGER;
  905.       val       : CatTypes.String255;
  906. BEGIN
  907.   lastPos := 0;
  908.   pos := 0;
  909.   count := 0;
  910.   WHILE (pos >= 0) DO
  911.     pos := Strings.Pos (":", str, lastPos);
  912.     IF (count = idx) & (pos > 0)
  913.     THEN
  914.       MagicStrings.Copy (str, lastPos, pos - lastPos, val);
  915.       MagicStrings.Append (val, target);
  916.       RETURN
  917.     END;
  918.     IF (pos < 0) & (count = idx)
  919.     THEN
  920.       (* letzter Parameter oder nur ein Wert *)
  921.       MagicStrings.Copy (str, lastPos, INTEGER(LENGTH (str)) - lastPos, val);
  922.       MagicStrings.Append (val, target);
  923.       (* MagicStrings.Append (str, target); *)
  924.       RETURN
  925.     END;
  926.     lastPos := pos+1;
  927.     INC (count);
  928.   END;
  929. END GetEnumValue;
  930.  
  931. PROCEDURE CheckRadioEnums (paramEnums: Lists.List; VAR str: ARRAY OF CHAR): BOOLEAN;
  932.   VAR pEnum : pOneEnum;
  933.       count : INTEGER;
  934. BEGIN
  935.   count := Lists.NoOfEntries (paramEnums);
  936.   Lists.ResetList (paramEnums);
  937.   pEnum := Lists.NextEntry (paramEnums);
  938.   WHILE pEnum # NIL DO
  939.     IF mtUtils.InState (theTree, pEnum^.obLow, MagicAES.SELECTED)
  940.     THEN
  941.       (* Ersten Wert aus Aufz„hlung nehmen! *)
  942.       GetEnumValue (0, pEnum^.enumValue, str);
  943.       RETURN TRUE;
  944.     ELSIF count = 1
  945.     THEN
  946.       (* Zweiten Wert aus Aufz„hlung nehmen! *)
  947.       GetEnumValue (1, pEnum^.enumValue, str);
  948.       RETURN TRUE;
  949.     END;
  950.     pEnum := Lists.NextEntry (paramEnums);
  951.   END;
  952.   (* Hier kommen wir nur hier, wenn keiner selektiert ist *)
  953.   RETURN count = 1;
  954. END CheckRadioEnums;
  955.  
  956. PROCEDURE CheckCheckEnums (paramEnums: Lists.List; VAR str: ARRAY OF CHAR): BOOLEAN;
  957.   VAR pEnum : pOneEnum;
  958.       count : INTEGER;
  959.       oneSet: BOOLEAN;
  960.       value : INTEGER;
  961. BEGIN
  962.   Lists.ResetList (paramEnums);
  963.   oneSet := FALSE;
  964.   pEnum := Lists.NextEntry (paramEnums);
  965.   WHILE pEnum # NIL DO
  966.     count := CheckEnumValue (pEnum^.enumValue);
  967.     IF count < 3
  968.     THEN
  969.       IF mtUtils.InState (theTree, pEnum^.obLow, MagicAES.SELECTED)
  970.       THEN
  971.         GetEnumValue (0, pEnum^.enumValue, str);
  972.         oneSet := TRUE;
  973.       END;
  974.     ELSIF count = 3
  975.     THEN
  976.       value := mtUtils.GetThreeState (theTree, pEnum^.obLow);
  977.       IF value = mtUtils.CLEAR
  978.       THEN
  979.         (* zweiten Wert aus Enum nehmen *)
  980.         GetEnumValue (1, pEnum^.enumValue, str);
  981.         oneSet := TRUE;
  982.       ELSIF value = mtUtils.SETNEW
  983.       THEN
  984.         (* ersten Wert aus Enum nehmen *)
  985.         GetEnumValue (0, pEnum^.enumValue, str);
  986.         oneSet := TRUE;
  987.       END;
  988.     ELSE
  989.       (* Nicht behandelbar momentan *)
  990.     END;
  991.     pEnum := Lists.NextEntry (paramEnums);
  992.   END;
  993.   RETURN oneSet;
  994. END CheckCheckEnums;
  995.  
  996. PROCEDURE GetParam (pParm: pOneParam; VAR str: ARRAY OF CHAR): BOOLEAN;
  997.   VAR bRes  : BOOLEAN;
  998.       value : CatTypes.String255;
  999.       dt    : ConvertDate.Date;
  1000.       temp  : CatTypes.String127;
  1001.       lIntVal   : LONGINT;
  1002.       pos   : CARDINAL;
  1003.       pName : CatTypes.String127;
  1004. BEGIN
  1005.   WITH pParm^ DO
  1006.     CASE paramType OF
  1007.       tpConst   : (* Konstanten Teil bernehmen *)
  1008.                   MagicStrings.Append (paramDflt, str);
  1009.                   RETURN TRUE; |
  1010.       tpEnum    : IF hasEnums 
  1011.                   THEN
  1012.                     bRes := CheckRadioEnums (paramEnum, str);
  1013.                     IF ~bRes
  1014.                     THEN
  1015.                       (* Fehlermeldung *)
  1016.                       StripShortcut (paramName, pName);
  1017.                       MTE.InfoAlert (eEnumCheck1, pName, eEnumCheck2);
  1018.                       RETURN FALSE;
  1019.                     END;
  1020.                   END;
  1021.                   RETURN TRUE; |
  1022.       tpEnumSet : IF hasEnums 
  1023.                   THEN 
  1024.                     bRes := CheckCheckEnums (paramEnum, str);
  1025.                     IF ~bRes
  1026.                     THEN
  1027.                       (* Fehlermeldung *)
  1028.                       StripShortcut (paramName, pName);
  1029.                       MTE.InfoAlert (eEnumCheck1, pName, eEnumCheck2);
  1030.                       RETURN FALSE;
  1031.                     END;
  1032.                   END; 
  1033.                   RETURN TRUE; |
  1034.       tpMTDate,
  1035.       tpDate    : (* Editfeld auslesen *)
  1036.                   mtUtils.ObjcString (theTree, obLow, value);
  1037.                   IF (value[0] = 0C)
  1038.                   THEN
  1039.                     IF ~optional
  1040.                     THEN
  1041.                       (* Fehlermeldung *)
  1042.                       StripShortcut (paramName, pName);
  1043.                       MTE.InfoAlert (eEmptyParm1, pName, eEmptyParm2);
  1044.                       RETURN FALSE;
  1045.                     END;
  1046.                   ELSIF ~ConvertDate.DateOk (value)
  1047.                   THEN
  1048.                     (* Fehlermeldung *)
  1049.                     StripShortcut (paramName, pName);
  1050.                     MTE.InfoAlert (eDateAlt1, pName, eDateAlt2);
  1051.                     RETURN FALSE;
  1052.                   ELSE
  1053.                     (* Datum konvertieren *)
  1054.                     IF paramType = tpMTDate
  1055.                     THEN
  1056.                       ConvertDate.StrToMTDate (value, temp);
  1057.                     ELSE
  1058.                       ConvertDate.TextToDate (value, dt, v.bool);
  1059.                       ConvertDate.DateToText (dt, "DD.MM.YYYY", temp);
  1060.                     END;
  1061.                     MagicStrings.Append (temp, str);
  1062.                   END;
  1063.                   RETURN TRUE; |
  1064.       tpUsername,
  1065.       tpGroup,
  1066.       tpChiefGroup,
  1067.       tpString,
  1068.       tpPassword,
  1069.       tpNewPassword:
  1070.                   mtUtils.ObjcString (theTree, obLow, value);
  1071.                   Strings.DelLeadingBlanks (value);
  1072.                   Strings.DelTrailingBlanks (value);
  1073.                   IF (value[0] = 0C)
  1074.                   THEN
  1075.                     IF ~optional
  1076.                     THEN
  1077.                       (* Fehlermeldung *)
  1078.                       StripShortcut (paramName, pName);
  1079.                       MTE.InfoAlert (eEmptyParm1, pName, eEmptyParm2);
  1080.                       RETURN FALSE;
  1081.                     END;
  1082.                   ELSE
  1083.                     MagicStrings.Append (value, str);
  1084.                   END;
  1085.                   RETURN TRUE; |
  1086.       tpInt,
  1087.       tpRange:    mtUtils.ObjcString (theTree, obLow, value);
  1088.                   Strings.DelBlanks (value);
  1089.                   IF (value[0] = 0C)
  1090.                   THEN
  1091.                     IF ~optional
  1092.                     THEN
  1093.                       (* Fehlermeldung *)
  1094.                       StripShortcut (paramName, pName);
  1095.                       MTE.InfoAlert (eEmptyParm1, pName, eEmptyParm2);
  1096.                       RETURN FALSE;
  1097.                     END;
  1098.                   ELSE
  1099.                     pos := 0;
  1100.                     lIntVal := StrConv.StrToLInt (value, pos, v.bool);
  1101.                     IF paramType = tpRange
  1102.                     THEN
  1103.                       IF (lIntVal < paramMin) OR (lIntVal > paramMax)
  1104.                       THEN
  1105.                         (* Fehlermeldung *)
  1106.                         StripShortcut (paramName, pName);
  1107.                         MagicStrings.Assign (eRangeAlt1, value);
  1108.                         MagicStrings.Append (pName, value);
  1109.                         MagicStrings.Append (eRangeAlt2, value);
  1110.                         MagicStrings.Append (StrConv.IntToStr (paramMin, 0), value);
  1111.                         MagicStrings.Append (eRangeAlt3, value);
  1112.                         MagicStrings.Append (StrConv.IntToStr (paramMax, 0), value);
  1113.                         MagicStrings.Append (eRangeAlt4, value);
  1114.                         
  1115.                         MTE.info (value);
  1116.                         RETURN FALSE;
  1117.                       END;
  1118.                     END;
  1119.                     IF lIntVal >= 0
  1120.                     THEN
  1121.                       MagicStrings.Assign ("+", value);
  1122.                     ELSE
  1123.                       MagicStrings.Assign ("", value);
  1124.                     END;
  1125.                     MagicStrings.Append (StrConv.IntToStr (lIntVal, 0), value);
  1126.                     MagicStrings.Append (value, str);
  1127.                   END;
  1128.                   RETURN TRUE; |
  1129.     ELSE
  1130.     END;
  1131.   END;
  1132.   RETURN TRUE;
  1133. END GetParam;
  1134.  
  1135. PROCEDURE WriteCmdToFile (REF str: ARRAY OF CHAR);
  1136.   VAR   fName   : CatTypes.String255;
  1137.         fHdl    : mtTextfiles.TEXTFILE;
  1138. BEGIN
  1139.   IF str[0] = 0C THEN RETURN END;
  1140.   MagicStrings.Assign (MTPaths.MessagePath, fName);
  1141.   MagicStrings.Append (CatTypes.userCmdFile, fName);
  1142.   IF mtTextfiles.OpenTextfile (fName, mtTextfiles.APPEND, 512, fHdl)
  1143.   OR mtTextfiles.OpenTextfile (fName, mtTextfiles.WRITE, 512, fHdl)
  1144.   THEN
  1145.     mtTextfiles.WriteChar (fHdl, ':');
  1146.     mtTextfiles.WriteLine (fHdl, str);
  1147.     mtTextfiles.WriteLn (fHdl);
  1148.     mtTextfiles.CloseTextfile (fHdl);
  1149.     Protokoll.SendPathUpdate (MTPaths.MessagePath);
  1150.   ELSE
  1151.     MTE.InfoAlert (MTE.noFile1, fName, MTE.noFile3);
  1152.   END;
  1153. END WriteCmdToFile;
  1154.  
  1155. PROCEDURE GetValues (pCmd: pOneCommand; doWrite: BOOLEAN; preview: BOOLEAN): BOOLEAN;
  1156.   VAR pParm : pOneParam;
  1157.       str   : CatTypes.String1023;
  1158.       tmp   : CatTypes.String255;
  1159. BEGIN
  1160.   (* Parameter und Objekte auslesen und prfen *)
  1161.   MagicStrings.Assign ("",str);
  1162.   WITH pCmd^ DO
  1163.     IF hasParms
  1164.     THEN
  1165.       Lists.ResetList (cmdParms);
  1166.       pParm := Lists.NextEntry (cmdParms);
  1167.       WHILE pParm # NIL DO
  1168.         IF ~GetParam (pParm, str)
  1169.         THEN
  1170.           RETURN FALSE
  1171.         END;
  1172.         pParm := Lists.NextEntry (cmdParms);
  1173.       END;
  1174.       IF doWrite
  1175.       THEN
  1176.         IF cmdType = tcConfig
  1177.         THEN
  1178.           (* Abfragen, ob es gespeichert oder nur einmal geschrieben werden soll *)
  1179.           MagicStrings.Assign (eSaveCmd1, tmp);
  1180.           MagicStrings.Append (cmdName, tmp);
  1181.           MagicStrings.Append (eSaveCmd2, tmp);
  1182.           v.int := mtAlerts.Alert (1, tmp);
  1183.           IF v.int = 1
  1184.           THEN
  1185.             (* Sichern in CATUSER.INF *)
  1186.             MagicStrings.Assign (cItkCmd, tmp);
  1187.             MagicStrings.Append (StrConv.IntToStr (cmdIdent, 0), tmp);
  1188.             v.bool := ConfVars.SetConfigString (tmp, str);
  1189.             MagicStrings.Assign (cItkCmdVersion, tmp);
  1190.             MagicStrings.Append (StrConv.IntToStr (cmdIdent, 0), tmp);
  1191.             v.bool := ConfVars.SetConfigInt (tmp, cmdVersion);
  1192.             ConfVars.GetConfDefInt (cItkCmdMax, v.int, -1);
  1193.             IF v.int < cmdIdent
  1194.             THEN
  1195.               v.bool := ConfVars.SetConfigInt (cItkCmdMax, cmdIdent);
  1196.             END;
  1197.             IF ~UserInformation.UserBLK.autosave
  1198.             THEN
  1199.               v.int := mtAlerts.Alert (1, eSaveConfig);
  1200.               IF v.int = 1
  1201.               THEN
  1202.                 CatUtil.WriteUserBlock();
  1203.               END;
  1204.             END;
  1205.           ELSIF v.int = 2
  1206.           THEN
  1207.             WriteCmdToFile (str);
  1208.           END;
  1209.         ELSE
  1210.           WriteCmdToFile (str);
  1211.         END;
  1212.       END;
  1213.       IF preview
  1214.       THEN
  1215.         MTE.InfoAlert (ePreview1, str, ePreview2);
  1216.       END;
  1217.     END;
  1218.   END;
  1219.   RETURN TRUE;
  1220. END GetValues;
  1221.  
  1222. (*----------------------------------------------------------------------
  1223.  * Parser fr das ITK 
  1224.  *----------------------------------------------------------------------*)
  1225.  
  1226. PROCEDURE ParseDataType (REF typeStr : ARRAY OF CHAR; VAR param: OneParam): BOOLEAN;
  1227.   VAR pos : CARDINAL;
  1228. BEGIN
  1229.   pos := 1;
  1230.   CASE typeStr[0] OF 
  1231.       'A' :   param.paramType := tpEnum; |
  1232.       'M' :   param.paramType := tpEnumSet; |
  1233.       'D' :   param.paramType := tpMTDate; |
  1234.       'd' :   param.paramType := tpDate; |
  1235.       'S',
  1236.       'P',
  1237.       'p' :   CASE typeStr[0] OF
  1238.                 'S' : param.paramType := tpString; |
  1239.                 'P' : param.paramType := tpPassword; |
  1240.                 'p' : param.paramType := tpNewPassword; |
  1241.               ELSE
  1242.               END;
  1243.               (* Maxl„nge auslesen *)
  1244.               param.paramMin := StrConv.StrToLInt (typeStr, pos, v.bool); |
  1245.       'U' :   param.paramType := tpUsername; |
  1246.       'I' :   IF Strings.Pos (',', typeStr, pos) > 0
  1247.               THEN
  1248.                 param.paramType := tpRange;
  1249.                 (* Direkt aufsplitten und Min und Max rauslesen *)
  1250.                 param.paramMin := StrConv.StrToLInt (typeStr, pos, v.bool);
  1251.                 INC (pos);    (* Komma berspringen *)
  1252.                 param.paramMax := StrConv.StrToLInt (typeStr, pos, v.bool);
  1253.               ELSE
  1254.                 param.paramType := tpInt; 
  1255.               END; |
  1256.       'G' :   param.paramType := tpGroup; |
  1257.       'g' :   param.paramType := tpChiefGroup; |
  1258.   ELSE
  1259.     globErr := errDataType;
  1260.     RETURN FALSE;
  1261.   END;
  1262.   param.optional := typeStr[pos] = 'o'; 
  1263.   RETURN TRUE;
  1264. END ParseDataType;
  1265.  
  1266. PROCEDURE WriteParam (VAR cConstant, cDataType: ARRAY OF CHAR;
  1267.                       VAR cParam: OneParam;
  1268.                       VAR cCmd  : OneCommand;
  1269.                       VAR paramDataDa : BOOLEAN): BOOLEAN;
  1270.   VAR pParam  : pOneParam;
  1271. BEGIN
  1272.   IF cConstant[0] # ""
  1273.   THEN
  1274.     cParam.paramType := tpConst;
  1275.     MagicStrings.Assign (cConstant, cParam.paramDflt);
  1276.   END;
  1277.   ALLOCATE (pParam, TSIZE (OneParam));
  1278.   IF pParam = NIL
  1279.   THEN
  1280.     RETURN FALSE
  1281.   END;
  1282.   (* Inhalt kopieren *)
  1283.   pParam^ := cParam;
  1284.   (* An Liste anh„ngen *)
  1285.   Lists.AppendEntry (cCmd.cmdParms, pParam, v.bool);
  1286.   (* Daten zurcksetzen *)
  1287.   paramDataDa := FALSE;
  1288.   MagicStrings.Assign ("", cConstant);
  1289.   MagicStrings.Assign ("", cDataType);
  1290.   MagicStrings.Assign ("", cParam.paramName);
  1291.   MagicStrings.Assign ("", cParam.paramDflt);
  1292.   cParam.paramMin := 0;
  1293.   cParam.paramMax := 0;
  1294.   cParam.optional := FALSE;
  1295.   cParam.paramHelp := NIL;
  1296.   cParam.hasEnums := FALSE;
  1297.   (* Und Returncode von AppendEntry zurckgeben *)
  1298.   RETURN ~v.bool;
  1299. END WriteParam;
  1300.  
  1301. PROCEDURE WriteEnumData (VAR param: OneParam; VAR enum: OneEnum;
  1302.                          VAR enumDataDa: BOOLEAN): BOOLEAN;
  1303.   VAR pEnum   : pOneEnum;
  1304. BEGIN
  1305.   ALLOCATE (pEnum, TSIZE (OneEnum));
  1306.   IF pEnum = NIL
  1307.   THEN
  1308.     RETURN FALSE;
  1309.   END;
  1310.   (* Inhalt kopieren *)
  1311.   pEnum^ := enum;
  1312.   (* An Liste anh„ngen *)
  1313.   Lists.AppendEntry (param.paramEnum, pEnum, v.bool);
  1314.   MagicStrings.Assign ("", enum.enumName);
  1315.   MagicStrings.Assign ("", enum.enumValue);
  1316.   enumDataDa := FALSE;
  1317.   RETURN ~v.bool;
  1318. END WriteEnumData;
  1319.  
  1320. PROCEDURE IsInternalCmd (VAR cCmd : OneCommand): BOOLEAN;
  1321.   VAR i : INTEGER;
  1322. BEGIN
  1323.   FOR i := 0 TO maxInternalCmds - 1 DO
  1324.     IF (cCmd.cmdIdent = internalCmds[i].intIdent)
  1325.     &  (cCmd.cmdVersion = internalCmds[i].intVersion)
  1326.     THEN
  1327.       RETURN TRUE;
  1328.     END;
  1329.   END;
  1330.   RETURN FALSE;
  1331. END IsInternalCmd;
  1332.  
  1333. PROCEDURE WriteCmd (VAR cmd: OneCommand; 
  1334.                     VAR cmdDataDa : BOOLEAN): BOOLEAN;
  1335.  VAR pCmd : pOneCommand;
  1336. BEGIN
  1337.   IF IsInternalCmd (cmd)
  1338.   THEN
  1339.     (* Speicher freigeben *)
  1340.     IF cmd.hasParms
  1341.     THEN
  1342.       DeleteSimpleList (cmd.cmdParms, TRUE, delParam);
  1343.     END;
  1344.     IF cmd.cmdHelp # NIL
  1345.     THEN
  1346.       DEALLOCATE (cmd.cmdHelp, 0);
  1347.     END;
  1348.     v.bool := FALSE;
  1349.   ELSE
  1350.     ALLOCATE (pCmd, TSIZE (OneCommand));
  1351.     IF pCmd = NIL
  1352.     THEN 
  1353.       RETURN FALSE
  1354.     END;
  1355.     (* Inhalt kopieren *)
  1356.     pCmd^ := cmd;
  1357.     pCmd^.selected := FALSE;
  1358.     (* An Liste anh„ngen *)
  1359.     Lists.AppendEntry (cmds, pCmd, v.bool);
  1360.   END;
  1361.   MagicStrings.Assign ("", cmd.cmdName);
  1362.   MagicStrings.Assign ("", cmd.cmdGroup);
  1363.   cmd.cmdVersion := 0;
  1364.   cmd.hasParms := FALSE;
  1365.   cmd.cmdHelp := NIL;
  1366.   
  1367.   cmdDataDa := FALSE;
  1368.   RETURN ~v.bool;
  1369. END WriteCmd;
  1370.  
  1371. PROCEDURE compITK (p1, p2: ADDRESS): BOOLEAN;
  1372.   VAR pA1, pA2 : POINTER TO pOneCommand;
  1373.         itk1, itk2 : pOneCommand;
  1374. BEGIN
  1375.   pA1 := p1;
  1376.   pA2 := p2;
  1377.   itk1 := pA1^;
  1378.   itk2 := pA2^;
  1379.   IF Strings.StrEqual (itk1^.cmdGroup, itk2^.cmdGroup)
  1380.   THEN
  1381.     RETURN Strings.Compare (itk1^.cmdName, itk2^.cmdName) = Strings.less;
  1382.   ELSE
  1383.     RETURN Strings.Compare (itk1^.cmdGroup, itk2^.cmdGroup) = Strings.less;
  1384.   END;
  1385. END compITK;
  1386.  
  1387. PROCEDURE SortList (VAR l : Lists.List; compProc: QuickSort.compProc);                        (* exported *)
  1388. (* sortiert die Gruppenliste *)
  1389.   VAR count : CARDINAL;
  1390.       sort  : POINTER TO ARRAY [0..$FFFF] OF ADDRESS;
  1391.       i     : CARDINAL;
  1392.       adr   : ADDRESS;
  1393. BEGIN
  1394.   count := Lists.NoOfEntries (l);
  1395.   IF count = 0 THEN RETURN END;
  1396.   ALLOCATE (sort, LONG(count) * TSIZE (ADDRESS));
  1397.   IF sort = NIL THEN RETURN END;
  1398.   Lists.ResetList (l);
  1399.   FOR i := 0 TO count-1 DO
  1400.     sort^[i] := Lists.NextEntry (l);
  1401.   END;
  1402.   v.bool := QuickSort.sortIt (0, count-1, sort^, compProc, TSIZE (ADDRESS), QuickSort.noBreak);
  1403.   (* Liste wieder zurckbernehmen *)
  1404.   Lists.ResetList (l);
  1405.   FOR i := 0 TO count-1 DO
  1406.     adr := Lists.NextEntry (l);
  1407.     Lists.RemoveEntry (l, v.bool);
  1408.   END;
  1409.   Lists.ResetList (l);
  1410.   FOR i := 0 TO count - 1 DO 
  1411.     Lists.AppendEntry (l, sort^[i], v.bool);
  1412.   END;
  1413.   DEALLOCATE (sort, 0);
  1414. END SortList;
  1415.  
  1416. PROCEDURE SortITK();
  1417. BEGIN
  1418.   SortList (cmds, compITK);
  1419. END SortITK;
  1420.  
  1421. PROCEDURE ParseITK(file: mtTextfiles.TEXTFILE): BOOLEAN;
  1422.   VAR   cDataType,
  1423.         cConstant   : CatTypes.String255;
  1424.         newPtr      : MidTextPtr;
  1425.         cParam      : OneParam;
  1426.         cEnum       : OneEnum;
  1427.         cCmd        : OneCommand;
  1428.         
  1429.         cmdDataDa   : BOOLEAN;
  1430.         enumDataDa  : BOOLEAN;
  1431.         paramDataDa : BOOLEAN;
  1432.         
  1433.         pos         : CARDINAL;
  1434.         scrap       : CatTypes.String255;
  1435.         cLineType   : CHAR;
  1436.  
  1437. BEGIN
  1438.  
  1439.   paramDataDa := FALSE;
  1440.   enumDataDa := FALSE;
  1441.   cmdDataDa := FALSE;
  1442.  
  1443.   cCmd.cmdHelp := NIL;
  1444.   cCmd.hasParms := FALSE;
  1445.   MagicStrings.Assign ("", cCmd.cmdGroup);
  1446.   cParam.paramHelp := NIL;
  1447.   cParam.hasEnums := FALSE;
  1448.   
  1449.   WHILE ~mtTextfiles.EndofText (file) DO
  1450.     mtTextfiles.ReadLine (file, scrap);
  1451.     mtTextfiles.ReadLn (file);
  1452.     (* Erstes Zeichen extrahieren und l”schen *)
  1453.     cLineType := scrap[0];
  1454.     MagicStrings.Delete (scrap, 0, 1);
  1455.     CASE cLineType OF
  1456.       '#' : (* ID des Kommandos *)
  1457.             IF enumDataDa
  1458.             THEN
  1459.               IF ~WriteEnumData (cParam, cEnum, enumDataDa)
  1460.               THEN
  1461.                 RETURN FALSE;
  1462.               END;
  1463.             END;
  1464.             IF paramDataDa
  1465.             THEN
  1466.               IF ~WriteParam(cConstant, cDataType, cParam, cCmd, paramDataDa)
  1467.               THEN
  1468.                 RETURN FALSE;
  1469.               END;
  1470.             END;
  1471.             IF cmdDataDa
  1472.             THEN
  1473.               IF ~WriteCmd (cCmd, cmdDataDa)
  1474.               THEN 
  1475.                 RETURN FALSE;
  1476.               END;
  1477.             END;
  1478.             pos := 0;
  1479.             cCmd.cmdIdent := StrConv.StrToInt (scrap, pos, v.bool); 
  1480.             cmdDataDa := TRUE; |
  1481.       'N' : (* Name des Kommandos *)
  1482.             MagicStrings.Assign (scrap, cCmd.cmdName); |
  1483.             
  1484.       'V' : (* Version des Kommandos *)
  1485.             pos := 0;
  1486.             cCmd.cmdVersion := StrConv.StrToInt (scrap, pos, v.bool); |
  1487.       
  1488.       'G' : (* Gruppe des Kommandos *)
  1489.             MagicStrings.Assign (scrap, cCmd.cmdGroup); |
  1490.             
  1491.       'H' : IF cCmd.cmdHelp = NIL
  1492.             THEN 
  1493.               ALLOCATE (cCmd.cmdHelp, LENGTH(scrap)+1);
  1494.               IF cCmd.cmdHelp # NIL
  1495.               THEN
  1496.                 MagicStrings.Assign (scrap, cCmd.cmdHelp^);
  1497.               ELSE
  1498.                 RETURN FALSE;
  1499.               END;
  1500.             ELSE
  1501.               ALLOCATE (newPtr, LENGTH (cCmd.cmdHelp^)+LENGTH (scrap) + 2);
  1502.               IF newPtr # NIL
  1503.               THEN
  1504.                 (* String zusammensetzen *)
  1505.                 MagicStrings.Assign (cCmd.cmdHelp^, newPtr^);
  1506.                 MagicStrings.Append (" ", newPtr^);
  1507.                 MagicStrings.Append (scrap, newPtr^);
  1508.                 DEALLOCATE (cCmd.cmdHelp, 0);
  1509.                 cCmd.cmdHelp := newPtr;
  1510.               ELSE
  1511.                 RETURN FALSE;
  1512.               END;
  1513.             END; |
  1514.       'T' : (* Kommandotyp *)
  1515.             CASE scrap[0] OF
  1516.                 'K' :   cCmd.cmdType := tcConfig; |
  1517.                 'E' :   cCmd.cmdType := tcSingle; |
  1518.                 'B' :   cCmd.cmdType := tcMultiple; |
  1519.             ELSE
  1520.               cCmd.cmdType := tcSingle;
  1521.             END; |
  1522.             
  1523.       'C' : (* Konstanter Syntax-Teil, neuer Parameter *)
  1524.             IF enumDataDa
  1525.             THEN
  1526.               IF ~WriteEnumData (cParam, cEnum, enumDataDa)
  1527.               THEN
  1528.                 RETURN FALSE;
  1529.               END;
  1530.             END;
  1531.             IF paramDataDa
  1532.             THEN
  1533.               IF ~WriteParam(cConstant, cDataType, cParam, cCmd, paramDataDa)
  1534.               THEN
  1535.                 RETURN FALSE;
  1536.               END;
  1537.             ELSE
  1538.               Lists.CreateList (cCmd.cmdParms, v.bool);
  1539.               IF v.bool
  1540.               THEN
  1541.                 RETURN FALSE;
  1542.               END;
  1543.               cCmd.hasParms := TRUE;
  1544.             END;
  1545.             MagicStrings.Assign (scrap, cConstant); 
  1546.             paramDataDa := TRUE; |
  1547.             
  1548.       'F' : (* Variabler Parameter, Datentyp *)
  1549.             IF enumDataDa
  1550.             THEN
  1551.               IF ~WriteEnumData (cParam, cEnum, enumDataDa)
  1552.               THEN
  1553.                 RETURN FALSE;
  1554.               END;
  1555.             END;
  1556.             IF paramDataDa
  1557.             THEN
  1558.               IF ~WriteParam(cConstant, cDataType, cParam, cCmd, paramDataDa)
  1559.               THEN
  1560.                 RETURN FALSE;
  1561.               END;
  1562.             ELSE
  1563.               Lists.CreateList (cCmd.cmdParms, v.bool);
  1564.               IF v.bool
  1565.               THEN
  1566.                 RETURN FALSE;
  1567.               END;
  1568.               cCmd.hasParms := TRUE;
  1569.             END;
  1570.             MagicStrings.Assign (scrap, cDataType); 
  1571.             IF ~ParseDataType (cDataType, cParam)
  1572.             THEN
  1573.               lastCmd := cCmd.cmdIdent;
  1574.               RETURN FALSE;
  1575.             END;
  1576.             paramDataDa := TRUE; |
  1577.  
  1578.       (* Einzelne Teile eines Parameters *)
  1579.       'K' : (* Name des Parameters *)
  1580.             MagicStrings.Assign (scrap, cParam.paramName); |
  1581.             
  1582.       'D' : (* Defaultwert des Parameters *)
  1583.             MagicStrings.Assign (scrap, cParam.paramDflt); |
  1584.             
  1585.       'L' : (* Hilfe zu einem Parameter *)
  1586.             IF cParam.paramHelp = NIL
  1587.             THEN 
  1588.               ALLOCATE (cParam.paramHelp, LENGTH(scrap)+1);
  1589.               IF cParam.paramHelp # NIL
  1590.               THEN
  1591.                 MagicStrings.Assign (scrap, cParam.paramHelp^);
  1592.               ELSE
  1593.                 RETURN FALSE;
  1594.               END;
  1595.             ELSE
  1596.               ALLOCATE (newPtr, LENGTH (cParam.paramHelp^)+LENGTH (scrap) + 2);
  1597.               IF newPtr # NIL
  1598.               THEN
  1599.                 (* String zusammensetzen *)
  1600.                 MagicStrings.Assign (cParam.paramHelp^, newPtr^);
  1601.                 MagicStrings.Append (" ", newPtr^);
  1602.                 MagicStrings.Append (scrap, newPtr^);
  1603.                 DEALLOCATE (cParam.paramHelp, 0);
  1604.                 cParam.paramHelp := newPtr;
  1605.               ELSE
  1606.                 RETURN FALSE;
  1607.               END;
  1608.             END; |
  1609.       'A' : (* Aufz„hlungsteil des Parameters *)
  1610.             IF enumDataDa
  1611.             THEN
  1612.               IF ~WriteEnumData (cParam, cEnum, enumDataDa)
  1613.               THEN
  1614.                 RETURN FALSE;
  1615.               END;
  1616.             ELSE
  1617.               Lists.CreateList (cParam.paramEnum, v.bool);
  1618.               IF v.bool
  1619.               THEN 
  1620.                 RETURN FALSE;
  1621.               END;
  1622.               cParam.hasEnums := TRUE;
  1623.             END;
  1624.             MagicStrings.Assign (scrap, cEnum.enumValue); 
  1625.             enumDataDa := TRUE; |
  1626.       'B' : (* Kurzbeschreibung eines Enumwertes *)
  1627.             MagicStrings.Assign (scrap, cEnum.enumName); |
  1628.     ELSE
  1629.     END;
  1630.   END;
  1631.   IF enumDataDa
  1632.   THEN
  1633.     IF ~WriteEnumData (cParam, cEnum, enumDataDa)
  1634.     THEN
  1635.       RETURN FALSE;
  1636.     END;
  1637.   END;
  1638.   IF paramDataDa
  1639.   THEN
  1640.     IF ~WriteParam(cConstant, cDataType, cParam, cCmd, paramDataDa)
  1641.     THEN
  1642.       RETURN FALSE;
  1643.     END;
  1644.   END;
  1645.   IF cmdDataDa
  1646.   THEN
  1647.     IF ~WriteCmd (cCmd, cmdDataDa)
  1648.     THEN 
  1649.       RETURN FALSE;
  1650.     END;
  1651.   END;
  1652.   (* Jetzt noch ITK sortieren *)
  1653.   SortITK ();
  1654.   
  1655.   RETURN TRUE;
  1656. END ParseITK;
  1657.   
  1658. PROCEDURE InitCmdList (): BOOLEAN;
  1659.   VAR file  : mtTextfiles.TEXTFILE;
  1660.       fname : CatTypes.String255;
  1661. BEGIN
  1662.   Lists.CreateList (cmds, v.bool);
  1663.   IF v.bool
  1664.   THEN
  1665.     MTE.noMemAlert();
  1666.     RETURN FALSE;
  1667.   END;
  1668.   IF ~Infofiles.GetInfoFilename ('ITK',fname)
  1669.   THEN
  1670.     MTE.info (noITKAlert);
  1671.     RETURN FALSE;
  1672.   END;
  1673.   IF mtTextfiles.OpenTextfile (fname, mtTextfiles.READ, 32767, file)
  1674.   THEN
  1675.     globErr := errMemErr;
  1676.     IF ~ParseITK (file)
  1677.     THEN
  1678.       mtTextfiles.CloseTextfile (file);
  1679.       CASE globErr OF
  1680.         errMemErr   : MTE.noMemAlert(); |
  1681.         errDataType : MTE.numAlert (lastCmd, eDataType); |
  1682.       ELSE
  1683.         MTE.info (eUnknown);
  1684.       END;
  1685.       (* Bisher allozierten Kram wieder freigeben *)
  1686.       FreeCmdList();
  1687.       RETURN FALSE;
  1688.     END;
  1689.     mtTextfiles.CloseTextfile (file);
  1690.   ELSE
  1691.     MTE.InfoAlert (MTE.noFile1, fname, MTE.noFile4);
  1692.     RETURN FALSE;
  1693.   END;
  1694.   
  1695.   RETURN TRUE;
  1696. END InitCmdList;
  1697.  
  1698. PROCEDURE FreeCmdList ();
  1699. BEGIN
  1700.   (* Liste wieder entfernen *)
  1701.   DeleteSimpleList (cmds, TRUE, delCmd);
  1702. END FreeCmdList;
  1703.  
  1704. (* Userinterface *)
  1705.  
  1706. PROCEDURE lineToStr (entry, env : ADDRESS; VAR str : ARRAY OF CHAR);
  1707.   VAR pCmd : pOneCommand;
  1708. BEGIN
  1709.   pCmd := entry;
  1710.   IF pCmd = NIL THEN RETURN END;
  1711.   MagicStrings.Assign (pCmd^.cmdName, str);
  1712. END lineToStr;
  1713.  
  1714. PROCEDURE selEntry (entry, env: ADDRESS; line : INTEGER): BOOLEAN;
  1715.   VAR pCmd : pOneCommand;
  1716. BEGIN
  1717.   pCmd := entry;
  1718.   IF pCmd = NIL THEN RETURN FALSE END;
  1719.   pCmd^.selected := ~pCmd^.selected;
  1720.   RETURN FALSE;
  1721. END selEntry;
  1722.  
  1723. PROCEDURE isSelected (entry, env : ADDRESS) : BOOLEAN;
  1724.   VAR pCmd : pOneCommand;
  1725. BEGIN
  1726.   pCmd := entry;
  1727.   IF pCmd = NIL THEN RETURN FALSE END;
  1728.   RETURN pCmd^.selected;
  1729. END isSelected;
  1730.  
  1731. PROCEDURE isEnabled (entry, env : ADDRESS) : BOOLEAN;
  1732. BEGIN
  1733.   RETURN TRUE
  1734. END isEnabled;
  1735.  
  1736. PROCEDURE countEntries ( l : ADDRESS; VAR ll: LONGINT; VAR ww: INTEGER);
  1737.  VAR lp     : POINTER TO Lists.List;
  1738. BEGIN
  1739.   lp := l;
  1740.   ww := globalLength * mtAppl.CharWidth;
  1741.   ll := VAL (LONGINT, Lists.NoOfEntries (lp^));
  1742. END countEntries;
  1743.  
  1744. VAR  tr     : mtUtils.tObjcTree;
  1745.      mTree  : ARRAY [0..1] OF MagicAES.OBJECT;
  1746.      mTed   : MagicAES.TEDINFO;
  1747.      mText  : ARRAY [0..255] OF CHAR;
  1748.  
  1749. PROCEDURE drawCmdEntry (entry, env : ADDRESS; x, y : INTEGER;
  1750.                          offset : INTEGER; clip   : GrafBase.Rectangle);
  1751.  
  1752. CONST spaceString = "                                                   ";
  1753.   VAR pCmd : pOneCommand;
  1754. BEGIN
  1755.   tr^[0].obX := x;
  1756.   tr^[0].obY := y;
  1757.   IF entry # NIL
  1758.   THEN
  1759.     (* Jetzt hier den String fr den Gruppennamen zusammenbauen *)
  1760.     pCmd := entry;
  1761.     mtUtils.SetObjcString (tr, 0, pCmd^.cmdName);
  1762.     mtUtils.SetState (tr, 0, MagicAES.SELECTED, isSelected (entry, env));
  1763.   ELSE
  1764.     mtUtils.SetObjcString (tr, 0, spaceString);
  1765.     mtUtils.SetState (tr, 0, MagicAES.SELECTED, FALSE);
  1766.   END;
  1767.   MagicAES.ObjcDraw (tr, 0, 8, clip);
  1768. END drawCmdEntry;
  1769.  
  1770. PROCEDURE itkButton (tree: ADDRESS; private: ADDRESS; button: INTEGER;
  1771.                      mx, my : INTEGER; kstate: BITSET; clicks: INTEGER): BOOLEAN;
  1772.   VAR str: CatTypes.String255;
  1773.       r  : GrafBase.Rectangle;
  1774.       pCmd: pOneCommand;
  1775.       help : Lists.List;
  1776. BEGIN
  1777.   button := INTEGER(BITSET(button) - {15});
  1778.   mtUtils.ExclState(tree, button, MagicAES.SELECTED);
  1779.   (* Jetzt mal nachsehen, was das fr ein Button ist.
  1780.    * Wenn es OK oder Abbruch ist, dann gehen wir raus
  1781.    *)
  1782.   pCmd := private;
  1783.   IF (button = helpButIdx) 
  1784.   THEN
  1785.     IF BuildHelp  (pCmd, help)
  1786.     THEN
  1787.       CatHelp.DoExternalHelp (help);
  1788.     END;
  1789.     WinDials.WinDialDraw (tree, button, 1, r, FALSE);
  1790.     RETURN FALSE;
  1791.   ELSIF (button = okButIdx) 
  1792.   THEN
  1793.     (* Valid-Check der einzelnen Elemente *)
  1794.     v.bool := GetValues (pCmd, FALSE, FALSE);
  1795.     IF ~v.bool
  1796.     THEN
  1797.       WinDials.WinDialDraw (tree, button, 1, r, FALSE);
  1798.     END;
  1799.     RETURN v.bool;
  1800.   ELSIF (button = previewButIdx)
  1801.   THEN
  1802.     (* Valid-Check der einzelnen Elemente *)
  1803.     v.bool := GetValues (pCmd, FALSE, TRUE);
  1804.     WinDials.WinDialDraw (tree, button, 1, r, FALSE);
  1805.     RETURN FALSE;
  1806.   ELSIF (button = cancelButIdx)
  1807.   THEN 
  1808.     RETURN TRUE
  1809.   ELSE
  1810.     (* User oder Gruppenbutton *)
  1811.     MagicStrings.Assign ("", str);
  1812.     IF mtUtils.InState (tree, button, Bit13)
  1813.     THEN
  1814.       (* Userselect *)
  1815.       mtUtils.ObjcString (tree, button+1, str);
  1816.       IF ListHelp.SelectName (str)
  1817.       THEN
  1818.         mtUtils.SetObjcString (tree, button+1, str);
  1819.       END;
  1820.     ELSIF mtUtils.InState (tree, button, Bit14)
  1821.     THEN
  1822.       (* Gruppenselect nur fr Chef *)
  1823.       mtUtils.ObjcString (tree, button+1, str);
  1824.       ListHelp.SetLastGroup (str);
  1825.       IF ListHelp.SelectGroup (str, v.card, FALSE, FALSE, FALSE, ListHelp.gsmChief)
  1826.       THEN
  1827.         mtUtils.SetObjcString (tree, button+1, str);
  1828.       END;
  1829.     ELSIF mtUtils.InState (tree, button, Bit15)
  1830.     THEN
  1831.       (* Gruppenselect *)
  1832.       mtUtils.ObjcString (tree, button+1, str);
  1833.       ListHelp.SetLastGroup (str);
  1834.       IF ListHelp.SelectGroup (str, v.card, FALSE, FALSE, FALSE, ListHelp.gsmOther)
  1835.       THEN
  1836.         mtUtils.SetObjcString (tree, button+1, str);
  1837.         WinDials.WinEditChanged (tree, button+1);
  1838.       END;
  1839.     ELSE
  1840.       RETURN FALSE;
  1841.     END;
  1842.     WinDials.WinDialDraw (tree, button, 1, r, FALSE);
  1843.     RETURN FALSE;
  1844.   END;
  1845.   RETURN FALSE;
  1846. END itkButton;
  1847.  
  1848. PROCEDURE itkGetSetValues (tree: ADDRESS; private: ADDRESS; 
  1849.                            set: BOOLEAN; exit: INTEGER);
  1850.   VAR pCmd: pOneCommand;
  1851. BEGIN
  1852.   IF ~set
  1853.   THEN
  1854.     IF exit = okButIdx
  1855.     THEN
  1856.       pCmd := private;
  1857.       v.bool := GetValues (pCmd, TRUE, FALSE);
  1858.     END;
  1859.   END;
  1860. END itkGetSetValues;
  1861.  
  1862. PROCEDURE HandleCommand (pCmd: pOneCommand);
  1863.   VAR exit : INTEGER;
  1864.       r    : GrafBase.Rectangle;
  1865. BEGIN
  1866.   BuildTree (pCmd);
  1867.   IF ~WinDials.OpenWinDial (theTree, TRUE, 
  1868.                             itkGetSetValues,
  1869.                             itkGetSetValues,
  1870.                             itkButton,
  1871.                             WinDials.defDraw,
  1872.                             "",
  1873.                             pCmd)
  1874.   THEN
  1875.     MTE.noWinDialAlert();
  1876.     RemoveTree ();
  1877.     FreeCmdList ();
  1878.     RETURN
  1879.   END;
  1880.   (* Leider ein modaler Dialog, da nicht reentrant *)
  1881.   WinDials.WinDialHandleEvents();
  1882.   RemoveTree ();
  1883.   FreeCmdList ();
  1884. END HandleCommand;
  1885.  
  1886. PROCEDURE setAndGetCmdValues (tree: ADDRESS; private: ADDRESS; set: BOOLEAN; exitBut: INTEGER);
  1887.   VAR pCmd : pOneCommand;
  1888.       pInt : POINTER TO INTEGER;
  1889. BEGIN
  1890.   IF ~set
  1891.   THEN
  1892.     pInt := private;
  1893.     pInt^ := exitBut;
  1894.   END;
  1895. END setAndGetCmdValues;
  1896.  
  1897. PROCEDURE doItkHelp (obj: INTEGER; env, info : ADDRESS; VAR draw : BOOLEAN; VAR exit : BOOLEAN);
  1898. BEGIN
  1899.   CatHelp.DoHelp (CatHelp.itkhelp);
  1900.   mtUtils.SetState (CmdBox, obj, MagicAES.SELECTED, FALSE);
  1901.   WinDials.WinDialDraw (CmdBox, obj, 1, v.r, FALSE);
  1902.   draw := FALSE;
  1903.   exit := FALSE;
  1904. END doItkHelp;
  1905.  
  1906. PROCEDURE SelectCmd (): BOOLEAN;
  1907.   VAR exit : INTEGER;
  1908.       specials : ARRAY [0..1] OF ListDl.specialButHdler;
  1909.       r        : GrafBase.Rectangle;
  1910.       dialHandler: ListDl.ldHandler;
  1911.       pCmd      : pOneCommand;
  1912. BEGIN
  1913.   IF ~InitCmdList()
  1914.   THEN
  1915.     RETURN FALSE;
  1916.   END;
  1917.   
  1918.   Lists.ResetList (cmds);
  1919.   pCmd := Lists.NextEntry (cmds);
  1920.   globalLength := 0;
  1921.   WHILE pCmd # NIL DO
  1922.     globalLength := BinOps.HigherInt (INTEGER(LENGTH(pCmd^.cmdName)), globalLength);
  1923.     pCmd := Lists.NextEntry (cmds);
  1924.   END;
  1925.   INC (globalLength, 2);
  1926.  
  1927.   (* Objektadresse holen *)
  1928.   CmdBox := MausTauschrsc.TreeAddr^[MausTauschrsc.cmdbox];
  1929.   specials[0].objc := MausTauschrsc.chelp;
  1930.   specials[0].proc := doItkHelp;
  1931.  
  1932.   (* Jetzt das Object zusammenbauen *)
  1933.   mtUtils.CalcArea (CmdBox, MausTauschrsc.ccmdbox, r);
  1934.   globalLength := BinOps.HigherInt (globalLength, r.w DIV mtAppl.CharWidth);
  1935.   
  1936.   (* Objectadresse holen *)
  1937.   tr := MausTauschrsc.TreeAddr^[MausTauschrsc.listtxt];
  1938.   Block.Copy (tr, TSIZE(MagicAES.OBJECT), ADR(mTree));
  1939.   Block.Copy (tr^[0].obSpec.TedPtr, TSIZE(MagicAES.TEDINFO), ADR(mTed));
  1940.   mTree[0].obSpec.TedPtr := ADR(mTed);
  1941.   mTree[0].obSpec.TedPtr^.tePtext := ADR (mText);
  1942.   tr := ADR (mTree);
  1943.   tr^[0].obSpec.TedPtr^.teTxtlen := globalLength;
  1944.   tr^[0].obWidth := globalLength * mtAppl.CharWidth;
  1945.   mtUtils.SetState (tr, 0, MagicAES.SELECTED, FALSE);
  1946.   mtUtils.SetState (tr, 0, MagicAES.DISABLED, FALSE);
  1947.  
  1948.   (* WindowDialog vorbereiten *)
  1949.   ListDl.BuildLdHandler (ADR(cmds), 
  1950.                          ListHelp.resetList,
  1951.                          ListHelp.nextEntry,
  1952.                          ListHelp.prevEntry,
  1953.                          countEntries, 
  1954.                          isEnabled, selEntry,
  1955.                          lineToStr, isSelected, 
  1956.                          drawCmdEntry,
  1957.                          0, mtAppl.CharHeight, 
  1958.                          mtAppl.CharWidth, globalLength * mtAppl.CharWidth,
  1959.                          dialHandler);
  1960.  
  1961.   (* ListWinDialog ”ffnen *)
  1962.   IF ListDl.WinListDial (CmdBox, ListDl.ldElemSet{ListDl.ldArrows, ListDl.ldSelect, ListDl.ldDoubleExit, ListDl.ldModal},
  1963.                        dialHandler,
  1964.                        MausTauschrsc.ccmdbox,
  1965.                        MausTauschrsc.ccmdback,
  1966.                        MausTauschrsc.cok,
  1967.                        MausTauschrsc.ccancel,
  1968.                        ADR(exit), MausTauschrsc.cok,
  1969.                        -1,
  1970.                        ListDl.dummyInLoop,
  1971.                        specials,
  1972.                        1,
  1973.                        ListDl.dummyCheckExit,
  1974.                        setAndGetCmdValues,
  1975.                        setAndGetCmdValues,
  1976.                        pCmd)
  1977.   THEN
  1978.     IF (exit = MausTauschrsc.cok) & (pCmd # NIL)
  1979.     THEN
  1980.       HandleCommand (pCmd);
  1981.     END;
  1982.   END;
  1983.   FreeCmdList();
  1984.   RETURN TRUE;
  1985. END SelectCmd;
  1986.  
  1987. (*$Z-*)
  1988. PROCEDURE GetVersion (elem, int: ADDRESS): BOOLEAN;
  1989.   VAR pInt : POINTER TO INTEGER;
  1990.       pCmd : pOneCommand;
  1991. BEGIN
  1992.   pInt := int;
  1993.   pCmd := elem;
  1994.   RETURN (pCmd # NIL) & (pCmd^.cmdIdent = pInt^);
  1995. END GetVersion;
  1996. (*$Z+*)
  1997.  
  1998. PROCEDURE GetCmdVersion (cmd: INTEGER; VAR version: INTEGER): BOOLEAN;
  1999.   VAR found: BOOLEAN;
  2000.       pCmd : pOneCommand;
  2001. BEGIN
  2002.   Lists.ScanEntries (cmds, Lists.forward, GetVersion, ADR(cmd), found);
  2003.   IF found
  2004.   THEN
  2005.     pCmd := Lists.CurrentEntry (cmds);
  2006.     version := pCmd^.cmdVersion;
  2007.   END;
  2008.   RETURN found;
  2009. END GetCmdVersion;
  2010.  
  2011. END DoITK.
  2012.